home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / net / sun4c.md / netLE.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  15KB  |  573 lines

  1. /* 
  2.  * netLE.c --
  3.  *
  4.  *    The main routines for the device driver for the AMD 7990 Ethernet 
  5.  *    Controller.
  6.  *
  7.  *
  8.  * TODO: Watch dogs to make sure that the chip does not get stuck.  Rumor has
  9.  *     it that because of bugs in the chip it can get stuck at any time for
  10.  *     no particular reason.
  11.  *
  12.  * Copyright 1988 Regents of the University of Californiaf
  13.  * Permission to use, copy, modify, and distribute this
  14.  * software and its documentation for any purpose and without
  15.  * fee is hereby granted, provided that the above copyright
  16.  * notice appear in all copies.  The University of California
  17.  * makes no representations about the suitability of this
  18.  * software for any purpose.  It is provided "as is" without
  19.  * express or implied warranty.
  20.  *
  21.  */
  22.  
  23. #ifndef lint
  24. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/net/sun4c.md/netLE.c,v 9.15 92/04/14 16:57:53 jhh Exp $ SPRITE (Berkeley)";
  25. #endif not lint
  26.  
  27. #include <sprite.h>
  28. #include <sys.h>
  29. #include <list.h>
  30. #include <netInt.h>
  31. #include <netLEInt.h>
  32. #include <vm.h>
  33. #include <vmMach.h>
  34. #include <mach.h>
  35. #include <machMon.h>
  36. #include <dbg.h>
  37. #include <assert.h>
  38. #ifdef sun4c
  39. #include <devSCSIC90.h>
  40. #endif
  41.  
  42.  
  43. /*
  44.  *----------------------------------------------------------------------
  45.  *
  46.  * NetLEInit --
  47.  *
  48.  *    Initialize the LANCE AMD 7990 Ethernet chip.
  49.  *
  50.  * Results:
  51.  *    SUCCESS if the LANCE controller was found and initialized,
  52.  *    FAILURE otherwise.
  53.  *
  54.  * Side effects:
  55.  *    Initializes the netEtherFuncs record, as well as the chip.
  56.  *
  57.  *----------------------------------------------------------------------
  58.  */
  59.  
  60. ReturnStatus
  61. NetLEInit(interPtr)
  62.     Net_Interface    *interPtr;     /* Network interface. */
  63. {
  64.     int         i;
  65.     List_Links        *itemPtr;
  66.     NetLEState        *statePtr;
  67.     ReturnStatus    status;
  68.     void        NetLETrace();
  69.  
  70.     assert(sizeof(NetLE_Reg) == NET_LE_REG_SIZE);
  71.     assert(sizeof(NetLEModeReg) == 2);
  72.     assert(sizeof(NetLERingPointer) == 4);
  73.     assert(sizeof(NetLEInitBlock) == 24);
  74.     assert(sizeof(NetLERecvMsgDesc) == 8);
  75.     assert(sizeof(NetLEXmitMsgDesc) == 8);
  76.  
  77.     statePtr = (NetLEState *) malloc (sizeof(NetLEState));
  78.     bzero((char *) statePtr, sizeof(NetLEState));
  79.     MASTER_LOCK(&interPtr->mutex)
  80.     statePtr->running = FALSE;
  81.     status = NetLEMachInit(interPtr, statePtr);
  82.     if (status != SUCCESS) {
  83.     MASTER_UNLOCK(&interPtr->mutex);
  84.     free((char *) statePtr);
  85.     return status;
  86.     }
  87.  
  88.     /*
  89.      * Initialize the transmission list.  
  90.      */
  91.  
  92.     statePtr->xmitList = &statePtr->xmitListHdr;
  93.     List_Init(statePtr->xmitList);
  94.  
  95.     statePtr->xmitFreeList = &statePtr->xmitFreeListHdr;
  96.     List_Init(statePtr->xmitFreeList);
  97.  
  98.     for (i = 0; i < NET_LE_NUM_XMIT_ELEMENTS; i++) {
  99.     itemPtr = (List_Links *) malloc(sizeof(NetXmitElement)), 
  100.     List_InitElement(itemPtr);
  101.     List_Insert(itemPtr, LIST_ATREAR(statePtr->xmitFreeList));
  102.     }
  103.  
  104.     /*
  105.      * Allocate the initialization block.
  106.      */
  107.     statePtr->initBlockPtr = 
  108.         (NetLEInitBlock *) BufAlloc(statePtr, sizeof(NetLEInitBlock));
  109.     interPtr->init    = NetLEInit;
  110.     interPtr->output     = NetLEOutput;
  111.     interPtr->intr    = NetLEIntr;
  112.     interPtr->ioctl    = NetLEIOControl;
  113.     interPtr->reset     = NetLERestart;
  114.     interPtr->getStats    = NetLEGetStats;
  115.     interPtr->netType    = NET_NETWORK_ETHER;
  116.     interPtr->maxBytes    = NET_ETHER_MAX_BYTES - sizeof(Net_EtherHdr);
  117.     interPtr->minBytes    = 0;
  118.     interPtr->interfaceData = (ClientData) statePtr;
  119.     status = Net_SetAddress(NET_ADDRESS_ETHER, 
  120.         (Address) &statePtr->etherAddress,
  121.         &interPtr->netAddress[NET_PROTO_RAW]);
  122.     if (status != SUCCESS) {
  123.     panic("NetLEInit: Net_SetAddress failed\n");
  124.     }
  125.     interPtr->broadcastAddress = netEtherBroadcastAddress;
  126.     interPtr->flags |= NET_IFLAGS_BROADCAST;
  127.     statePtr->interPtr = interPtr;
  128.     statePtr->recvMemInitialized = FALSE;
  129.     statePtr->recvMemAllocated = FALSE;
  130.     statePtr->xmitMemInitialized = FALSE;
  131.     statePtr->xmitMemAllocated = FALSE;
  132.     statePtr->resetPending = FALSE;
  133.  
  134.     /*
  135.      * Reset the world.
  136.      */
  137.  
  138.     NetLEReset(interPtr);
  139.  
  140.     /*
  141.      * Now we are running.
  142.      */
  143.  
  144.     statePtr->running = TRUE;
  145.     MASTER_UNLOCK(&interPtr->mutex);
  146.     return (SUCCESS);
  147. }
  148.  
  149.  
  150. /*
  151.  *----------------------------------------------------------------------
  152.  *
  153.  * NetLEReset --
  154.  *
  155.  *    Reset the interface.
  156.  *
  157.  * Results:
  158.  *    None.
  159.  *
  160.  * Side effects:
  161.  *    All of the pointers in the interface structure are initialized.
  162.  *
  163.  *----------------------------------------------------------------------
  164.  */
  165.  
  166. void
  167. NetLEReset(interPtr)
  168.     Net_Interface    *interPtr; /* Interface to reset. */
  169. {
  170.     volatile NetLEInitBlock *initPtr;
  171.     NetLEState            *statePtr;
  172.     int                i;
  173.     int                j;
  174.     unsigned short        csr0;
  175.  
  176.     statePtr = (NetLEState *) interPtr->interfaceData;
  177.     /*
  178.      * If there isn't a reset pending already, and the chip is currently
  179.      * transmitting then just set the pending flag.  With any luck
  180.      * this mechanism will prevent the chip from being reset right in
  181.      * the middle of a packet.
  182.      */
  183.     if (!(statePtr->resetPending) && (statePtr->transmitting)) {
  184.     printf("Deferring reset.\n");
  185.     statePtr->resetPending = TRUE;
  186.     return;
  187.     }
  188.     statePtr->resetPending = FALSE;
  189.     /* 
  190.      * Reset (and stop) the chip.
  191.      */
  192.     NetBfShortSet(statePtr->regPortPtr->addrPort, AddrPort, NET_LE_CSR0_ADDR);
  193.     Mach_EmptyWriteBuffer();
  194.     statePtr->regPortPtr->dataPort = NET_LE_CSR0_STOP;
  195.     interPtr->flags &= ~NET_IFLAGS_RUNNING;
  196. #ifdef sun4c
  197.     Dev_ScsiResetDMA();
  198. #endif
  199.  
  200.     /*
  201.      * Set up the receive and transmit rings. 
  202.      */
  203.      NetLERecvInit(statePtr);
  204.      NetLEXmitInit(statePtr);
  205.  
  206.     /*
  207.      *  Fill in the initialization block. Make everything zero unless 
  208.      *  told otherwise.
  209.      */
  210.  
  211.     bzero( (Address) statePtr->initBlockPtr, sizeof(NetLEInitBlock));
  212.     initPtr = statePtr->initBlockPtr;
  213.  
  214.     /*
  215.      * Insert the ethernet address.
  216.      */
  217.  
  218. #ifndef ds5000
  219.     {
  220.     Net_EtherAddress    revAddr;
  221.     revAddr.byte2 = statePtr->etherAddress.byte1;
  222.     revAddr.byte1 = statePtr->etherAddress.byte2;
  223.     revAddr.byte4 = statePtr->etherAddress.byte3;
  224.     revAddr.byte3 = statePtr->etherAddress.byte4;
  225.     revAddr.byte6 = statePtr->etherAddress.byte5;
  226.     revAddr.byte5 = statePtr->etherAddress.byte6;
  227.     bcopy((char *) &revAddr, (char *) &initPtr->etherAddress, 
  228.     sizeof(statePtr->etherAddress));
  229.     }
  230. #else
  231.     bcopy((char *) &statePtr->etherAddress, (char *) &initPtr->etherAddress, 
  232.     sizeof(statePtr->etherAddress));
  233. #endif
  234.  
  235.     /*
  236.      * Reject all multicast addresses, except for those generated by bootp.
  237.      * These are address ab-00-00-01-00-00 = hash bit 31, maybe?
  238.      */
  239.  
  240.     initPtr->multiCastFilter[0] = 0x8000; /* Bit 31 apparently. */
  241.     initPtr->multiCastFilter[1] = 0;
  242.     initPtr->multiCastFilter[2] = 0;
  243.     initPtr->multiCastFilter[3] = 0;
  244.  
  245.     /*
  246.      * Set up the ring pointers.
  247.      */
  248.  
  249.     NetBfShortSet(initPtr->recvRing, LogRingLength, 
  250.         NET_LE_NUM_RECV_BUFFERS_LOG2);
  251.     NetBfShortSet(initPtr->recvRing, RingAddrLow, 
  252.         NET_LE_TO_CHIP_ADDR_LOW(statePtr->recvDescFirstPtr));
  253.     NetBfShortSet(initPtr->recvRing, RingAddrHigh, 
  254.         NET_LE_TO_CHIP_ADDR_HIGH(statePtr->recvDescFirstPtr));
  255.  
  256.     NetBfShortSet(initPtr->xmitRing, LogRingLength, 
  257.         NET_LE_NUM_XMIT_BUFFERS_LOG2);
  258.     NetBfShortSet(initPtr->xmitRing, RingAddrLow, 
  259.         NET_LE_TO_CHIP_ADDR_LOW(statePtr->xmitDescFirstPtr));
  260.     NetBfShortSet(initPtr->xmitRing, RingAddrHigh, 
  261.         NET_LE_TO_CHIP_ADDR_HIGH(statePtr->xmitDescFirstPtr));
  262.  
  263.     /*
  264.      * Set the the Bus master control register (csr3) to have chip byte
  265.      * swap for us. he sparcStation appears to need active low and
  266.      * byte control on.
  267.      */
  268.  
  269.     NetBfShortSet(statePtr->regPortPtr->addrPort, AddrPort, NET_LE_CSR3_ADDR);
  270.     Mach_EmptyWriteBuffer();
  271.     statePtr->regPortPtr->dataPort = 0;
  272.     Mach_EmptyWriteBuffer();
  273.     statePtr->regPortPtr->dataPort = NET_LE_CSR3_VALUE;
  274.  
  275.     /*
  276.      * Set the init block pointer address in csr1 and csr2
  277.      */
  278.     NetBfShortSet(statePtr->regPortPtr->addrPort, AddrPort, NET_LE_CSR1_ADDR);
  279.     Mach_EmptyWriteBuffer();
  280.     NetBfShortSet(&statePtr->regPortPtr->dataPort, DataCSR1, 
  281.         NET_LE_TO_CHIP_ADDR_LOW(initPtr));
  282.     Mach_EmptyWriteBuffer();
  283.  
  284.     NetBfShortSet(statePtr->regPortPtr->addrPort, AddrPort, NET_LE_CSR2_ADDR);
  285.     Mach_EmptyWriteBuffer();
  286.     NetBfShortSet(&statePtr->regPortPtr->dataPort, DataCSR2, 
  287.         NET_LE_TO_CHIP_ADDR_HIGH(initPtr));
  288.     Mach_EmptyWriteBuffer();
  289.  
  290.     /*
  291.      * Tell the chip to initialize and wait for results.
  292.      */
  293.     csr0 = 0;
  294.     for (j = 0; (j < 100) && ((csr0 & NET_LE_CSR0_INIT_DONE) == 0); j++) {
  295.     NetBfShortSet(statePtr->regPortPtr->addrPort, AddrPort, 
  296.         NET_LE_CSR0_ADDR);
  297.     Mach_EmptyWriteBuffer();
  298.     statePtr->regPortPtr->dataPort = NET_LE_CSR0_INIT;
  299.     Mach_EmptyWriteBuffer();
  300.  
  301.  
  302.     for (i = 0; i < 10000; i++) {
  303.         csr0 = statePtr->regPortPtr->dataPort;
  304.         if (csr0 & NET_LE_CSR0_INIT_DONE) {
  305.         break;
  306.         }
  307.     }
  308.     if (csr0 & NET_LE_CSR0_INIT_DONE) {
  309.         break;
  310.     }
  311.     }
  312.     if (!(csr0 & NET_LE_CSR0_INIT_DONE)) {
  313.     panic("LE ethernet: Chip will not initialize, csr0 = 0x%x\n", csr0);
  314.     }
  315.     MACH_DELAY(100);
  316.  
  317.     /*
  318.      * Ack the interrupt.
  319.      */
  320.     statePtr->regPortPtr->dataPort = NET_LE_CSR0_INIT_DONE;
  321.  
  322.     /*
  323.      * Start the chip and enable interrupts.
  324.      */
  325.     statePtr->regPortPtr->dataPort = 
  326.     (NET_LE_CSR0_START | NET_LE_CSR0_INTR_ENABLE);
  327.  
  328.     printf("LE ethernet: Reinitialized chip.\n");
  329.     statePtr->numResets++;
  330.     interPtr->flags |= NET_IFLAGS_RUNNING;
  331.     return;
  332. }
  333.  
  334.  
  335. /*
  336.  *----------------------------------------------------------------------
  337.  *
  338.  * NetLERestart --
  339.  *
  340.  *    Reinitialize the LANCE Ethernet chip.
  341.  *
  342.  * Results:
  343.  *    None.
  344.  *
  345.  * Side effects:
  346.  *    None.
  347.  *
  348.  *----------------------------------------------------------------------
  349.  */
  350. void
  351. NetLERestart(interPtr)
  352.     Net_Interface    *interPtr;     /* Interface to restart. */
  353. {
  354.  
  355.     NetLEState    *statePtr = (NetLEState *) interPtr->interfaceData;
  356.  
  357.     MASTER_LOCK(&interPtr->mutex);
  358.  
  359.     /*
  360.      * Drop the current packet so the sender does't get hung.
  361.      */
  362.     NetLEXmitDrop(statePtr);
  363.  
  364.     /*
  365.      * Reset the world.
  366.      */
  367.     NetLEReset(interPtr);
  368.  
  369.     /*
  370.      * Restart transmission of packets.
  371.      */
  372.     NetLEXmitRestart(statePtr);
  373.  
  374.     MASTER_UNLOCK(&interPtr->mutex);
  375.     return;
  376. }
  377.  
  378.  
  379. /*
  380.  *----------------------------------------------------------------------
  381.  *
  382.  * NetLEIntr --
  383.  *
  384.  *    Process an interrupt from the LANCE chip.
  385.  *
  386.  * Results:
  387.  *    None.
  388.  *
  389.  * Side effects:
  390.  *    None.
  391.  *
  392.  *----------------------------------------------------------------------
  393.  */
  394. void
  395. NetLEIntr(interPtr, polling)
  396.     Net_Interface    *interPtr;    /* Interface to process. */
  397.     Boolean        polling;    /* TRUE if are being polled instead of
  398.                      * processing an interrupt. */
  399. {
  400.     register    NetLEState    *statePtr;
  401.     ReturnStatus        statusXmit, statusRecv;
  402.     unsigned     short        csr0;
  403.     Boolean            reset;
  404.  
  405.     statePtr = (NetLEState *) interPtr->interfaceData;
  406.  
  407.     NetBfShortSet(statePtr->regPortPtr->addrPort, AddrPort, NET_LE_CSR0_ADDR);
  408.     Mach_EmptyWriteBuffer();
  409.     csr0 = statePtr->regPortPtr->dataPort;
  410.     if (netDebug) {
  411.     printf("NetLEIntr: %s, csr0 = 0x%x\n", (polling == TRUE) ? "polling" : 
  412.         "not polling", csr0);
  413.     }
  414.     if (csr0 & NET_LE_CSR0_STOP) {
  415.     printf("NetLEIntr: chip is stopped.\n");
  416.     NetLERestart(interPtr);
  417.     return;
  418.     }
  419.  
  420.     csr0 &= ~NET_LE_CSR0_INTR_ENABLE;
  421.     statePtr->regPortPtr->dataPort = csr0;
  422.     statePtr->regPortPtr->dataPort = NET_LE_CSR0_INTR_ENABLE;
  423.     if ( !((csr0 & NET_LE_CSR0_ERROR) || (csr0 & NET_LE_CSR0_INTR)) ) {
  424.     /*
  425.      * We could be polling; that's why we were here.
  426.      */
  427.     if (!polling) {
  428.         printf("LE ethernet: Spurious interrupt CSR0 = <%x>\n", csr0);
  429.         NetLERestart(interPtr);
  430.     } 
  431.     return;
  432.     } 
  433.  
  434.     /*
  435.      * Check for errors.
  436.      */
  437.  
  438.     if (csr0 & NET_LE_CSR0_ERROR) {
  439.     reset = TRUE;
  440.     if (csr0 & NET_LE_CSR0_MISSED_PACKET) {
  441.         printf("LE ethernet: Missed a packet.\n");
  442.         /*
  443.          * Don't reset controller.
  444.          */
  445.         reset = FALSE;
  446.     }
  447.     if (csr0 & NET_LE_CSR0_COLLISION_ERROR) {
  448.         /*
  449.          * Late collision error appear to happen when the machine
  450.          * is disconnected from the transceiver. When this happens
  451.          * we will complain about Lost of Carrier so the late
  452.          * collision message is uncessary.
  453.          *
  454.          * printf("LE ethernet: Late collision.\n");
  455.          */
  456.         reset = FALSE;
  457.     }
  458.     /*
  459.      * Check for fatal errors.  Kill the machine if we start babbling 
  460.      * (sending oversize ethernet packets). 
  461.      */
  462.     if (csr0 & NET_LE_CSR0_BABBLE) {
  463.         NetLEReset(interPtr);
  464.         panic("LE ethernet: Transmit babble\n");
  465.     }
  466.     if (csr0 & NET_LE_CSR0_MEMORY_ERROR) {
  467.         printf(
  468.     "statePtr: 0x%x, regPortPtr = 0x%x, dataPort = 0x%x, csr0: 0x%x\n", 
  469.         statePtr, statePtr->regPortPtr, statePtr->regPortPtr->dataPort, 
  470.         csr0);
  471.         panic("LE ethernet: Memory Error.\n");
  472.     }
  473.     /*
  474.      * Clear the error the easy way, reinitialize everything.
  475.      */
  476.     if (reset == TRUE) {
  477.         NetLERestart(interPtr);
  478.         return;
  479.     }
  480.     }
  481.  
  482.     statusRecv = statusXmit = SUCCESS;
  483.     /*
  484.      * Did we receive a packet.
  485.      */
  486.     if (csr0 & NET_LE_CSR0_RECV_INTR) {
  487.     statusRecv = NetLERecvProcess(FALSE, statePtr);
  488.     }
  489.     /*
  490.      * Did we transmit a packet.
  491.      */
  492.     if (csr0 & NET_LE_CSR0_XMIT_INTR) {
  493.     statusXmit = NetLEXmitDone(statePtr);
  494.     }
  495.     /*
  496.      * Did the chip magically initialize itself?
  497.      */
  498.     if (csr0 & NET_LE_CSR0_INIT_DONE) {
  499.     printf( "LE ethernet: Chip initialized itself!!\n");
  500.     /*
  501.      * Better initialize it the way we want it.
  502.      */
  503.     statusRecv = FAILURE;
  504.     }
  505.  
  506.     if (statusRecv != SUCCESS || statusXmit != SUCCESS) {
  507.     NetLERestart(interPtr);
  508.     return;
  509.     }
  510.     /*
  511.      * If interrupts aren't enabled or there is no interrupt pending, then
  512.      * what are we doing here?
  513.      */
  514.  
  515.     return;
  516. }
  517.  
  518. /*
  519.  *----------------------------------------------------------------------
  520.  *
  521.  * NetLEGetStats --
  522.  *
  523.  *    Return the statistics for the interface.
  524.  *
  525.  * Results:
  526.  *    A pointer to the statistics structure.
  527.  *
  528.  * Side effects:
  529.  *    None.
  530.  *
  531.  *----------------------------------------------------------------------
  532.  */
  533.  
  534. ReturnStatus
  535. NetLEGetStats(interPtr, statPtr)
  536.     Net_Interface    *interPtr;        /* Current interface. */
  537.     Net_Stats        *statPtr;        /* Statistics to return. */
  538. {
  539.     NetLEState    *statePtr;
  540.     statePtr = (NetLEState *) interPtr->interfaceData;
  541.     MASTER_LOCK(&interPtr->mutex);
  542.     statPtr->ether = statePtr->stats;
  543.     MASTER_UNLOCK(&interPtr->mutex);
  544.     return SUCCESS;
  545. }
  546.  
  547. /*
  548.  *----------------------------------------------------------------------
  549.  *
  550.  * NetLEIOControl --
  551.  *
  552.  *    Perform ioctls for the adapter.  Right now we don't support any.
  553.  *
  554.  * Results:
  555.  *    DEV_INVALID_ARG
  556.  *
  557.  * Side effects:
  558.  *    None.
  559.  *
  560.  *----------------------------------------------------------------------
  561.  */
  562.  
  563. /*ARGSUSED*/
  564. ReturnStatus
  565. NetLEIOControl(interPtr, ioctlPtr, replyPtr)
  566.     Net_Interface *interPtr;    /* Interface on which to perform ioctl. */
  567.     Fs_IOCParam *ioctlPtr;    /* Standard I/O Control parameter block */
  568.     Fs_IOReply *replyPtr;    /* Size of outBuffer and returned signal */
  569. {
  570.     return DEV_INVALID_ARG;
  571. }
  572.  
  573.